home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
pcmagazi
/
1992
/
11
/
rdump
/
rdump.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-17
|
5KB
|
175 lines
/*--------------------------------------
RDUMP.C -- RIFF Dumper for DOS
(c) Charles Petzold, 1992
--------------------------------------*/
#include <stdio.h>
#include <string.h>
typedef unsigned int BOOL ;
#define TRUE 1
#define FALSE 0
#define min(a,b) ((a) < (b) ? (a) : (b))
#define HIWORD(l) ((unsigned int) ((l) >> 16))
#define LOWORD(l) ((unsigned int) ((l) & 65535))
long DumpChunk (FILE * file, BOOL bWithinInfoForm, int iLevel)
{
static char szBuffer [4096] ;
BOOL bRiffChunk, bListChunk, bInfoForm ;
char szChunkType [5], szFormType [5] ;
int i, iReadBytes ;
long lChunkSize, lChunkSizeFile, lFilePos1, lFilePos2, lBytesRead ;
// Get the file position to later calculate number of bytes read
fgetpos (file, &lFilePos1) ;
// Read the chunk type and verify that it's in a correct format
if (fread (szChunkType, 1, 4, file) != 4)
return 0 ;
szChunkType [4] = '\0' ;
if (strlen (szChunkType) < 4)
return 0 ;
// Set Boolean values if the chunk type if "RIFF" or "LIST"
bRiffChunk = strcmp (szChunkType, "RIFF") == 0 ? TRUE : FALSE ;
bListChunk = strcmp (szChunkType, "LIST") == 0 ? TRUE : FALSE ;
if (iLevel == 0 && !bRiffChunk)
return 0 ;
// Read the chunk size, and display the type and size
if (fread (&lChunkSize, 1, 4, file) != 4)
return 0 ;
printf ("%.*s%s %04X-%04X", iLevel + 1, "\t\t\t\t", szChunkType,
HIWORD (lChunkSize), LOWORD (lChunkSize)) ;
if (bRiffChunk == 1 || bListChunk == 1)
{
// For a RIFF or LIST, read the form type
if (fread (szFormType, 1, 4, file) != 4)
{
printf ("\n") ;
return 0 ;
}
szFormType [4] = '\0' ;
if (strlen (szFormType) < 4)
return 0 ;
// Set Boolean value if form type is "INFO", and print it
bInfoForm = strcmp (szFormType, "INFO") == 0 ? bListChunk : FALSE ;
printf (" %s\n", szFormType) ;
lChunkSize -= 4 ;
// Recursively dump the chunks
while (lChunkSize > 0)
{
if (0 == (lBytesRead = DumpChunk (file, bInfoForm, iLevel + 1)))
return 0 ;
lChunkSize -= lBytesRead ;
if (lChunkSize < 0)
return 0 ;
}
}
else
{
// If it's not a RIFF or LIST, find the chunk size
lChunkSizeFile = ~1 & (lChunkSize + 1) ;
iReadBytes = (int) (min (lChunkSizeFile, sizeof (szBuffer))) ;
if ((int) fread (szBuffer, 1, iReadBytes, file) != iReadBytes)
return 0 ;
// Display the first 24 characters of an INFO
// string or the first 8 bytes of binary data
if (bWithinInfoForm)
printf (" \"%.24s\"%s\n", szBuffer,
lChunkSize > (long) 25 ? " ..." : "") ;
else
{
for (i = 0 ; i < min (8, lChunkSize) ; i++)
printf (" %02X", (unsigned char) szBuffer [i]) ;
printf ("%s\n", lChunkSize > (long) 8 ? " ..." : "") ;
}
lChunkSizeFile -= iReadBytes ;
// Continue reading the chunk until it's exhausted
while (lChunkSizeFile > 0)
{
iReadBytes = (int) (min (lChunkSizeFile, sizeof (szBuffer))) ;
if ((int) fread (szBuffer, 1, iReadBytes, file) != iReadBytes)
return 0 ;
lChunkSizeFile -= iReadBytes ;
}
}
// Determine how many bytes have been read, and return them
fgetpos (file, &lFilePos2) ;
return lFilePos2 - lFilePos1 ;
}
int main (int argc, char * argv [])
{
FILE * file ;
int i ;
// Syntax message if no filenames on command line
if (argc < 2)
{
fprintf (stderr, "Syntax: RDUMP [filename...]") ;
return 1 ;
}
// For each filename, display the name and call DumpChunk
for (i = 1 ; i < argc ; i++)
{
printf ("\n%s\n\n", argv [i]) ;
if (NULL == (file = fopen (argv [i], "rb")))
{
fprintf (stderr, "\n\tCannot open file.\n", argv [i]) ;
fclose (file) ;
continue ;
}
if (0 == DumpChunk (file, FALSE, 0))
fprintf (stderr, "\n\tFile has incorrect format.\n",
argv [i]) ;
fclose (file) ;
}
return 0 ;
}